#include "controller.h"


static const char *TAG = "controller";


// 设备指针定义
#if (CONTROLLER_DEVICE_TYPE == 4)
    static rotary_encoder_t *encoder = NULL; 
#elif (CONTROLLER_DEVICE_TYPE == 1)
    static esp_lcd_touch_handle_t tp = NULL;   
#endif





esp_err_t input_device_init(void){

#if CONTROLLER_DEVICE_TYPE == 4
    // Rotary encoder underlying device is represented by a PCNT unit in this example
    uint32_t pcnt_unit = 0;
    // Create rotary encoder instance
    rotary_encoder_config_t config = ROTARY_ENCODER_DEFAULT_CONFIG((rotary_encoder_dev_t)pcnt_unit, ENCODER_A_PUL_PIN, ENCODER_B_PUL_PIN);
    ESP_ERROR_CHECK(rotary_encoder_new_ec11(&config, &encoder));
    // Filter out glitch (1us)
    ESP_ERROR_CHECK(encoder->set_glitch_filter(encoder, 1));
    // Start encoder
    ESP_ERROR_CHECK(encoder->start(encoder));

    // Enter key init
    gpio_config_t key_conf = {
        .intr_type = GPIO_INTR_DISABLE,
        .mode = GPIO_MODE_INPUT,
        .pin_bit_mask = (1ULL<<ENCODER_ENTER_PIN),
        .pull_down_en = GPIO_PULLDOWN_DISABLE,
        .pull_up_en = GPIO_PULLUP_DISABLE
    };
    ESP_ERROR_CHECK(gpio_config(&key_conf));


#elif CONTROLLER_DEVICE_TYPE == 2
    // Enter key init
    gpio_config_t key_conf = {
        .intr_type = GPIO_INTR_DISABLE,
        .mode = GPIO_MODE_INPUT,
        .pin_bit_mask = ((1ULL<<BUTTON_ENTER_PIN) | (1ULL<<BUTTON_LEFT_PIN) | (1ULL<<BUTTON_RIGHT_PIN)),
        .pull_down_en = GPIO_PULLDOWN_DISABLE,
        .pull_up_en = GPIO_PULLUP_ENABLE
    };
    ESP_ERROR_CHECK(gpio_config(&key_conf));


#elif CONTROLLER_DEVICE_TYPE == 1
    esp_lcd_panel_io_handle_t tp_io_handle = NULL;
    ESP_LOGI(TAG, "Initialize I2C");
    const i2c_config_t i2c_conf = {
        .mode = I2C_MODE_MASTER,
        .sda_io_num = POINTER_SDA_PIN,
        .scl_io_num = POINTER_CLK_PIN,
        .sda_pullup_en = GPIO_PULLUP_ENABLE,
        .scl_pullup_en = GPIO_PULLUP_ENABLE,
        .master.clk_speed = 400000,
    };
    /* Initialize I2C */
    ESP_ERROR_CHECK(i2c_param_config(0, &i2c_conf));
    ESP_ERROR_CHECK(i2c_driver_install(0, i2c_conf.mode, 0, 0, 0));
    esp_lcd_panel_io_i2c_config_t tp_io_config = ESP_LCD_TOUCH_IO_I2C_FT5x06_CONFIG();
    ESP_LOGI(TAG, "Initialize touch IO (I2C)");
    /* Touch IO handle */
    ESP_ERROR_CHECK(esp_lcd_new_panel_io_i2c((esp_lcd_i2c_bus_handle_t)0, &tp_io_config, &tp_io_handle));
    esp_lcd_touch_config_t tp_cfg = {
        .x_max = LCD_H_RES,
        .y_max = LCD_V_RES,
        .rst_gpio_num = POINTER_RST_PIN,
        .int_gpio_num = POINTER_INT_PIN,
        .flags = {
            .swap_xy = LCD_SWAP_XY,
            .mirror_x = LCD_MIRROR_X,
            .mirror_y = LCD_MIRROR_Y,
        },
    };
    ESP_LOGI(TAG, "Initialize touch controller FT5X06");
    ESP_ERROR_CHECK(esp_lcd_touch_new_i2c_ft5x06(tp_io_handle, &tp_cfg, &tp));

#endif
    
    ESP_LOGI(TAG, "Input device ready");
    return ESP_OK;
}





/**
 * @description: lvgl输入设备扫描回调函数
 * @param {lv_indev_drv_t} *indev_driver
 * @param {lv_indev_data_t} *data
 * @return {*}
 */
void indev_read_cb(struct _lv_indev_drv_t * indev_drv, lv_indev_data_t * data){

#if (CONTROLLER_DEVICE_TYPE == 4)
    static int64_t encoder_num_last = 0;
    // Enter key
    if (gpio_get_level(ENCODER_ENTER_PIN) == 0)
        data->state = LV_INDEV_STATE_PRESSED;
    else {
        int8_t encoder_dir = 0;
		int encoder_num_now = encoder->get_counter_value(encoder);
		if (encoder_num_now < encoder_num_last-2){
			encoder_dir = -1;	// left
			encoder_num_last = encoder->get_counter_value(encoder);
		} else if (encoder_num_now > encoder_num_last+2){
			encoder_dir = 1;	// right
			encoder_num_last = encoder->get_counter_value(encoder);
		}
		data->state = LV_INDEV_STATE_RELEASED;
		data->enc_diff = encoder_dir;
    }


#elif CONTROLLER_DEVICE_TYPE == 2
    if (gpio_get_level(BUTTON_ENTER_PIN) == 0){
        data->state = LV_INDEV_STATE_PRESSED;
        data->key = LV_KEY_ENTER;
    } else if (gpio_get_level(BUTTON_LEFT_PIN) == 0){
        data->state = LV_INDEV_STATE_PRESSED;
        data->key = LV_KEY_LEFT;
    } else if (gpio_get_level(BUTTON_RIGHT_PIN) == 0){
        data->state = LV_INDEV_STATE_PRESSED;
        data->key = LV_KEY_RIGHT;
    } else {
        data->state = LV_INDEV_STATE_RELEASED;
        // data->key = 0;
    }


#elif CONTROLLER_DEVICE_TYPE == 1
    esp_lcd_touch_read_data(tp);
    uint16_t touch_x[1];
    uint16_t touch_y[1];
    uint16_t touch_strength[1];
    uint8_t touch_cnt = 0;
    bool touchpanel_pressed = esp_lcd_touch_get_coordinates(tp, touch_x, touch_y, touch_strength, &touch_cnt, 1);
    if (touchpanel_pressed) {
        // printf("x:%d y:%d\n", touch_x[0], touch_y[0]);
        data->point.x = touch_x[0];
        data->point.y = touch_y[0];
        data->state = LV_INDEV_STATE_PRESSED;
    } else {
        data->state = LV_INDEV_STATE_RELEASED;
    }

#endif
    
} 




